package com.paper.tiger.easy.rpc.s.client.execute;

import com.paper.tiger.easy.rpc.s.client.SpringContextSupport;
import com.paper.tiger.easy.rpc.s.client.common.Dove;
import com.paper.tiger.easy.rpc.s.client.common.Letter;
import com.paper.tiger.easy.rpc.s.client.common.LetterType;
import io.netty.channel.ChannelHandlerContext;
import org.springframework.aop.support.AopUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * [简要描述]: 调用具体的方法
 * [详细描述]:
 *
 * @author ZouHaiBo
 * @version 1.0, 2021/6/17 19:48
 * @since JDK 1.8
 */
public class ExecuteFlyDove implements FlyDove
{

    @Override
    public void service(Dove wrap, ChannelHandlerContext ctx)
    {
        Letter remote = wrap.getLetter();
        Dove result = new Dove();
        Object invoke = null;
        try
        {
            Object bean = SpringContextSupport.getBean(remote.getServiceId());
            Class<?> aClass = bean.getClass();
            Method method = aClass.getMethod(remote.getMethod(), remote.getParamsTypes());

            invoke = AopUtils.invokeJoinpointUsingReflection(bean, method, remote.getArgs());

        }
        catch (Throwable e)
        {

            result.setExceptionFlag(true);
            if (e instanceof InvocationTargetException){
                InvocationTargetException targetException = (InvocationTargetException) e;
                e = targetException.getTargetException();
                e.printStackTrace();
            }else {
                e.printStackTrace();
            }
            result.setE(e);
        }

        result.setReturnNull(invoke == null);
        result.setDoveId(wrap.getDoveId());
        result.setAsyncClass(wrap.getAsyncClass());
        result.setSync(result.getAsyncClass() == null);
        result.setLetterType(LetterType.DOVE_RESPONSE.getCode());
        result.setResult(invoke);
        ctx.writeAndFlush(result);
    }
}
